This post demonstrates how oct2py can be used to run legacy Matlab/Octave code to load data saved in NeuroExplorer files into Python. As will be illustrated in a forthcoming post, this same approach can be used to run existing Matlab/Octave code in an integrated Jupyter notebook with Python kernel.
Matlab/Octave code for working with NEx files and a test file can be obtained from the NeuroExplorer website.
My lab has used an older set of m files written by Alex Kirillov (author of NeuroExplorer) and updated by us to deal with changes in Matlab over the years. We no longer use Matlab and our older m files for reading NEx files work perfectly well in GNU Octave. The three main files that we use are available from our GitHub repository: nex_info, nex_ts, and nex_cont.
In [1]:
import numpy as np
from scipy.io import loadmat
%load_ext oct2py.ipython
In [2]:
%cd ~/Desktop/Spikes-and-Fields/NEx-demo
Read files in an Octave session
The command %octave is the "octave magic" function that let's you run raw Matlab/Octave code in a Python notebook.
For a batch of commenda, use %%octave in the first line of a code cell. The rest of the cell is pure Octave/Matlab code. %%octave -o var returns a variable from the cell directly to the Python memoryspace.
In [3]:
%octave [nvar, names, types] = nex_info('TestDataFileForNeuroshare.nex');
%octave_pull and %octave_push are used to send variables between Octave and Python.
In [4]:
%octave_pull nvar names types
In [5]:
%whos
Some issues come up with variable types using this approach, and a few adjustments are needed once the variables are pulled into Python.
In [6]:
nvar = nvar.astype(int) # nvar should really be an integer
types = types.flatten() # types should really be a flat array
In [7]:
%whos
Let's load the neuron's time stamps into Python
In [8]:
names[types==0]
Out[8]:
It is very easy to load the variables that are needed into the Octave session, save them into a mat file, and load them into Python using SciPy's loadmat function.
Let's say we want to bring in one of the continuous recordings (ContChannel01) and a behavioral event (Event04) for an LFP using the MNE toolbox.
In [9]:
%%octave
[~, Event04] = nex_ts('TestDataFileForNeuroshare.nex', 'Event04');
[adfreq, n, ts, fn, AD01] = nex_cont('TestDataFileForNeuroshare.nex', 'ContChannel01');
In [10]:
%octave_pull Event04 adfreq ts AD01
%whos
Again, the time stamps and continuous variables need to be flattened.
The floating point numbers are fine. (adfreq is the sampling frequency and ts is the time difference between saving time stamps in the Plexon recording system and the continuous signals on the AD card.)
In [11]:
AD01 = AD01.flatten()
Event04 = Event04.flatten()
%whos